<?php

declare(strict_types=1);

namespace app\admin\controller;


use isszz\captcha\rotate\CaptchaException;
use isszz\captcha\rotate\facade\Captcha;
use isszz\captcha\rotate\support\File;


use think\Response;
use think\Request;

/**
 * 图片旋转验证码
 */
class RotateCaptcha
{

    // 获取你存储素材的根目录
    private function upload_path(string $path = 'rotate_captcha'): string
    {
        return public_path(DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . ($path ? ltrim($path, DIRECTORY_SEPARATOR) : $path));
    }


    /**
     * 生成验证码图片和相关信息
     */
    public function rotate()
    {

        // 新增: 从指定目录随机读取文件，这个方法不知道效率如何，基于FilesystemIterator类实现
        $image = File::make($this->upload_path('rotate_captcha'))->rand();

        // 生成验证码需要的图片
        // setLang设置语言
        $data = Captcha::setLang('zh-cn')->create(
            $image,
            $this->upload_path('rotate_captcha') // 用于存储生成图片的目录
        )->get(260); // 260为最终生成的图片尺寸

        if (!$data) {
            $this->result(1, 'error');
        }
        // $data['str']是图片的path加密, 用于前端交换验证码图片
        // 这里前端不涉及拿到角度, 都是去后端验证
        // 可以使用header传递token为X-CaptchaToken
        $this->result(0, 'success', ['str' => $data['str']], ['X-CaptchaToken' => $data['token']]);
    }

    /**
     * 验证
     */
    public function verify(Request $request)
    {
        $angle = $request->get('angle');
        // 优先从header获取token
        $token = $request->header('X-CaptchaToken') ?: $request->get('token');

        if (
            empty($token) || empty($angle)
        ) {
            $this->result(1, 'error');
        }

        try {
            if (Captcha::setLang('zh-cn')->check($token, $angle) === true) {
                session('rcvr', true);
                $this->result(0, 'success');
            }
        } catch (CaptchaException $e) {
            $this->result(1, $e->getMessage());
        }

        $this->result(1, 'error');
    }

    /**
     * 通过前端传递str字段给后端叫唤图片显示到前端
     */
    public function img(Request $request)
    {
        $str = $request->get('id');

        [$mime, $image] = Captcha::output($str, $this->upload_path('rotate_captcha'));

        if (empty($image)) {
            return '';
        }

        return response($image, 200, [
            'Cache-Control' => 'private, no-cache, no-store, must-revalidate',
            'Content-Type' => $mime,
            'Content-Length' => strlen($image)
        ]);
    }

    /**
     * 返回json
     */
    public function result(int|string $code = 0, string $msg = 'success', mixed $data = null, array $header = [])
    {
        $result = [
            'code' => $code,
            'data' => $data,
            'msg' => lang($msg) ?: ($code > 0 ? 'error' : 'success'),
        ];

        $response = Response::create($result, 'json')->code(200);

        if (!empty($header)) {
            $response = $response->header($header);
        }
        throw new \think\exception\HttpResponseException($response);
    }
}